package net.xuele.learn.ohc;

import com.google.common.base.Charsets;
import org.caffinitas.ohc.*;
import org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * @Author patrick
 * @Date 2023/2/6 11:12
 * @Description
 */
public class OhcDemo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        OHCache<String, String
                > ohCache = OHCacheBuilder.<String, String>newBuilder()
                .keySerializer(OhcDemo.stringSerializer)
                .eviction(Eviction.LRU)
                .executorService(new ScheduledThreadPoolExecutor(2))
                .valueSerializer(OhcDemo.stringSerializer)
                .timeouts(true)
                .build();

        ohCache.put("123", "patrick", System.currentTimeMillis() + 5000);
        ohCache.put("12345453631123445.ewwe.3124556.wqqew455,554554", "1");
//        ohCache.put("hello", "patrick");
        System.out.println("ohCache.get(12345453631123445.ewwe.3124556.wqqew455,554554) = " + ohCache.get("12345453631123445.ewwe.3124556.wqqew455,554554"));
        System.out.println("ohCache.get(123) = " + ohCache.get("xxxx"));
        Scanner sc = new Scanner(System.in);
        Map<String, Integer> map = new HashMap<>();
        while (sc.hasNext()) {
            String k = sc.next();
//            if (k.startsWith("s ")) {
//                String[] s = k.split(" ");
//            } else if (k.startsWith("g ")) {
//                System.out.println(k + "------" + ohCache.get(k));
//            } else {
//
//            }
            String vv;
            try {
                vv = ohCache.getWithLoaderAsync(k, kk -> {
                    System.out.println("try ..." + kk);
                    if (k.equals("err")) {
                        throw new PermanentLoadException();
                    }

                    if (map.getOrDefault(k, 0) > 1) {
                        map.put(k, map.getOrDefault(k, 0) + 1);
                        return k + "_123";
                    } else {
                        return k + "___";
                    }


                }, System.currentTimeMillis() + 5000).get();
            } catch (Exception e) {
                vv = System.currentTimeMillis() % 2 == 0 ? "odd" : "evenly";
            }
            System.out.println(k + "------" + vv);
        }
        sc.close();
    }

    public static final CacheSerializer<String> stringSerializer = new CacheSerializer<String>() {
        public void serialize(String s, ByteBuffer buf) {
            // 得到字符串对象UTF-8编码的字节数组
            byte[] bytes = s.getBytes(Charsets.UTF_8);
            // 用前16位记录数组长度
            buf.put((byte) ((bytes.length >>> 8) & 0xFF));
            buf.put((byte) ((bytes.length) & 0xFF));
            buf.put(bytes);
        }

        public String deserialize(ByteBuffer buf) {
            // 获取字节数组的长度
            int length = (((buf.get() & 0xff) << 8) + ((buf.get() & 0xff)));
            byte[] bytes = new byte[length];
            // 读取字节数组
            buf.get(bytes);
            // 返回字符串对象
            return new String(bytes, Charsets.UTF_8);
        }

        public int serializedSize(String s) {
            byte[] bytes = s.getBytes(Charsets.UTF_8);
            // 设置字符串长度限制，2^16 = 65536
            if (bytes.length > 65535)
                throw new RuntimeException("encoded string too long: " + bytes.length + " bytes");

            return bytes.length + 2;
        }
    };
}
